package com.qyer.search.sort;

import static com.qyer.log.WarningLogger.logWarning;
import static com.qyer.search.model.lastminute.SKU.unknownPositionSKU;
import static com.qyer.search.utils.ModelUtils.mergeType1;

import com.google.common.collect.Lists;
import com.qyer.commons.mc.MutableCache;
import com.qyer.search.cache.mutable.MutableCaches;
import com.qyer.search.exception.SearchException;
import com.qyer.search.model.SearchParameterOrigin;
import com.qyer.search.model.SecondComparableTuple2;
import com.qyer.search.model.lastminute.SKU;
import com.qyer.search.model.result.SearchPackage;
import com.qyer.search.model.result.Type1SearchPackage;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/**
 * Created by tangzheng on 16/4/20.
 */
public class PriceSorter implements SearchResultSorter{
  private SearchParameterOrigin sp;
  private SearchPackage searchPackage;
  private int orderDirection ;
  private int limit;

  public PriceSorter(SearchParameterOrigin sp, SearchPackage searchPackage, int orderDirection, int limit) {
    this.sp = sp;
    this.searchPackage = searchPackage;
    this.orderDirection = orderDirection;
    this.limit = limit;

  }

  @Override public List<SearchPackage> sortSearchPackages() throws SearchException {
    if(searchPackage == null){
      return null;
    }

    //System.out.println("PRICE :"+ limit);

    Map<Integer,Long> price = MutableCaches.getInstance().PRICE.getCacheContent();

    List<SearchPackage> sortedPackages = new ArrayList<>(1);
    List<SKU> skus;
    skus = searchPackage.getSkus();
    int size = skus.size();
    List<SKU> unknownList = new ArrayList<>(size);
    Map<Long,List<SKU>> treeSkuMap = null;
    if(orderDirection == 0)
      treeSkuMap = new TreeMap<>();
    if(orderDirection == 1)
      treeSkuMap = new TreeMap<>(new Comparator<Long>() {
        @Override public int compare(Long o1, Long o2) {
          return (o2.intValue()-o1.intValue());
        }
      });
    //skus = searchPackage.getSkus();
    //int size = skus.size();
    SKU sku;
    int id;
    long sale;

    long t1 = System.currentTimeMillis();

    for(int i = 0; i < size; i++){
      sku = skus.get(i);
      try {
        id = sku.getId();
        sale = price.get(id);
        //System.out.println("ID:"+id+",PRICE:"+sale);
        if(treeSkuMap.containsKey(sale)){
          treeSkuMap.get(sale).add(sku);
        }else {
          List<SKU> skuList = new ArrayList<>();
          skuList.add(sku);
          treeSkuMap.put(sale, skuList);
        }
      }catch (Exception e){
        if(sku != null)
          unknownList.add(sku);
      }
    }

    long t2 = System.currentTimeMillis();

    /*for(int i = 0; i<unknownList.size(); i++){
      System.out.println("UNKNOWN:"+unknownList.get(i).getId());
    }*/

    int l = limit;
    skus = Lists.newArrayListWithCapacity(size);
    Iterator<Map.Entry<Long, List<SKU>>> iterator = treeSkuMap.entrySet().iterator();
    while (iterator.hasNext() && l > 0) {
      Map.Entry<Long, List<SKU>> entry = iterator.next();
      List<SKU> skuList = entry.getValue();
      //System.out.println("PRICE:"+entry.getKey()+",ID:"+sku1.getId());
      skus.addAll(skuList);
      l = l - skuList.size();
    }

    long t3 = System.currentTimeMillis();
    //System.out.println("1COST:"+(t2-t1));
    //System.out.println("2COST:"+(t3-t2));
    if(l < 0){
      int sizee = skus.size();
      int ll = sizee + l;
      for(int j = (sizee-1); j >= ll; j--){
        skus.remove(j);
      }

    }else if(l > 0){
      if(l >= unknownList.size())
        skus.addAll(unknownList);
      else
        skus.addAll(unknownList.subList(0,l));
    }
    SearchPackage searchPackage = new SearchPackage(skus.size());
    searchPackage.addSkus(skus);
    sortedPackages.add(searchPackage);

    return sortedPackages;
  }
}